<!--
This example demonstrates the minimum amount of code required to use Mergely.
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8"/>
    <title>Mergely - Simple Example</title>
    <meta http-equiv="X-UA-Compatible" content="chrome=1, IE=edge">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <meta name="description" content="Merge and Diff your documents with diff online and share"/>
    <meta name="keywords" content="diff,merge,compare,jsdiff,comparison,difference,file,text,unix,patch,algorithm,saas,longest common subsequence"/>
    <meta name="author" content="Jamie Peabody"/>

    <!-- Requires jQuery -->
    <script type="text/javascript" src="../../jquery.min.js"></script>

    <!-- Requires CodeMirror -->
<!--    <script type="text/javascript" src="../lib/codemirror_5.32.0.min.js"></script>-->
    <script type="text/javascript" src="../../sql/codemirror.js"></script>
    <script type="text/javascript" src="../../sql/matchbrackets.js"></script>
    <script type="text/javascript" src="../../sql/sql.js"></script>
    <script type="text/javascript" src="../../sql/show-hint.js"></script>
    <script type="text/javascript" src="../../sql/sql-hint3.js"></script>
    <script type="text/javascript" src="../../sql/sql-hint-sybn.js"></script>
    <script type="text/javascript" src="../../sql/hint/html-hint.js"></script>
    <script type="text/javascript" src="../../sql/hint/javascript-hint.js"></script>
<!--    <script type="text/javascript" src="../lib/searchcursor.min.js"></script>-->
    <script type="text/javascript" src="../../sql/searchcursor.min.js"></script>
<!--    <link type="text/css" rel="stylesheet" href="../lib/codemirror_5.32.0.min.css"/>-->
    <link rel="stylesheet" href="../../../../css/plugin/sql/codemirror.css" />
    <link rel="stylesheet" href="../../../../css/bootstrap_sybn_custom.css" />

    <!-- Requires Mergely -->
    <script type="text/javascript" src="../lib/mergely.js"></script>
    <script type="text/javascript" src="../../gzip/pako.min.js"></script>
    <script type="text/javascript" src="../../gzip/base64_gzip.js"></script>
    <link type="text/css" rel="stylesheet" href="../lib/mergely.css"/>
    <style>.mergely-resizer {height: calc(100% - 1.8em);font-size: 13px;}
        .hidden {display:none}
        .mergely.ch.d.lhs {background-color: #ffe9e9;text-decoration: none;color: red !important;}
    </style>

    <script type="text/javascript">
$(document).ready(function () {
	var lDef = '-- 测试sql \n select * \n from aaa \n where bbb = ccc \n group by ddd\n limit 100';
	var rDef = '-- 测试sql \n select 1,2,3 \n from aaa \n where bbb != ccc \n GROUP BY ddd\n limit 1000';
	var wrap_lines = getQueryString('wrap_lines', 'true') == 'true';
	var z = getQueryString('z', '');
	if (z) {
		var zParam = unzip(z) // zParam: l=1111&r=2222
		lDef = getQueryString('l', '', zParam);
		rDef = getQueryString('r', '', zParam);
	}
    var ignorecaseStr = getQueryString('ignorecase');
    var ignorecaseVar = !ignorecaseStr || ignorecaseStr != "false";
    var modeStr = getQueryString('mode');
    $("#mode_select").val(modeStr);
	// https://www.mergely.com/doc
	$('#mergely').mergely({
		license: 'lgpl-separate-notice',
		ignorews: true, // 是否忽略空白差异
		ignorecase: ignorecaseVar, // 是否忽略大小写差异
		cmsettings: {mode: modeStr ? modeStr : 'text/plain', readOnly: false},
		wrap_lines: wrap_lines, // 自动换行
		lhs: function(setValue) {
			var lZip=getQueryString('lzip');
			var lText=getQueryString('l', lDef);
			if (lZip) {
				lText=unzip(lZip);
			}
			setValue(lText);
		},
		rhs: function(setValue) {
			var rZip=getQueryString('rzip');
			var rText=getQueryString('r', rDef);
			if (rZip) {
				rText=unzip(rZip);
			}
			setValue(rText);
		}
	});
});

// 新窗口打开
function newWindow(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	var param = "l=" + encodeURIComponent(lText) + "&r=" + encodeURIComponent(rText);
	var pzip = zip(param);

    var ignorecaseStr = getQueryString('ignorecase');
    var ignorecaseVar = !ignorecaseStr || ignorecaseStr != "false";
	window.open("?z=" + pzip + "&ignorecase=" + ignorecaseVar);
}

// 排序
function sortLine(asc){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	var lText2 = lText.split("\n").sort(asc ? compareFunction : compareFunctionDesc).join("\n");
	var rText2 = rText.split("\n").sort(asc ? compareFunction : compareFunctionDesc).join("\n");
	$("#mergely").mergely('lhs', lText2);
	$("#mergely").mergely('rhs', rText2);
};

// 切换大小写敏感
function ignorecaseAction(){
    var ignorecaseStr = getQueryString('ignorecase');
    var ignorecaseVar = !ignorecaseStr || ignorecaseStr != "false";

	$('#mergely').mergely('options', {ignorecase: !ignorecaseVar});
    var url2 = changeURLPar(window.location.href.toString(), "ignorecase", ""+!ignorecaseVar);
    window.history.pushState({},0,url2);
};

// 切换自动换行敏感
function wrapLinesAction(){
	var wrap_lines = getQueryString('wrap_lines', 'true') == 'true';

	$('#mergely').mergely('options', {wrap_lines: !wrap_lines});
    var url2 = changeURLPar(window.location.href.toString(), "wrap_lines", ""+!wrap_lines);
    window.history.pushState({},0,url2);
};

function compareFunction(param1, param2) {
    return param1.localeCompare(param2,"zh");
}
function compareFunctionDesc(param1, param2) {
    return param2.localeCompare(param1,"zh");
}

/**
 * 获取指定请求参数.
 *
 * @param name 参数名 必填
 * @param defaults 默认值, 可选
 * @param url 可选, 默认为当前页url
 */
function getQueryString(name, defaults, url) {
  var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(&|$)", "i");
  var r = (url) ? url.match(reg) : window.location.search.substr(1).match(reg);
  if (r != null) return decodeURIComponent(r[2]);
  return typeof defaults != undefined ? defaults : null;
}

/**
 * 替换url中的参数
 */
function changeURLPar(url, key, value) {
  var replaceText = key + '=' + (value == null || typeof(value) == undefined ? "" : encodeURIComponent(value));
  if (url.match('[?&]' + key + '=([^&]*)')) {
    return url.replace(eval('/' + key + '=[^&]*/'), replaceText);
  } else {
    if (url.match('\\?'))  {
      return url + '&' + replaceText;
    } else {
      return url + '?' + replaceText;
    }
  }
}

// 两边大写
function strUpperCase(upperCase){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	if (upperCase) {
		$("#mergely").mergely('lhs', lText.toUpperCase());
		$("#mergely").mergely('rhs', rText.toUpperCase());
	} else {
		$("#mergely").mergely('lhs', lText.toLowerCase());
		$("#mergely").mergely('rhs', rText.toLowerCase());
	}
};

// 忽略null
function ignoreNull(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', replaceNull(lText));
	$("#mergely").mergely('rhs', replaceNull(rText));
};

function replaceNull(source){
    if (!source) {
        return "";
    }
    return source.replace(/null/ig, "    ");
}

// 忽略时分秒
function ignoreTime(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', replaceTime(lText));
	$("#mergely").mergely('rhs', replaceTime(rText));
};

function replaceTime(source){
    if (!source) {
        return "";
    }
    return source.replace(/ \d\d:\d\d:\d\d(.\d\d\d)?/g, "");
}

// 忽略时分秒
function ignoreDateTime(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', replaceDateTime(lText));
	$("#mergely").mergely('rhs', replaceDateTime(rText));
};

function replaceDateTime(source){
    if (!source) {
        return "";
    }
    return source.replace(/\d\d\d\d-\d\d-\d\d( \d\d:\d\d:\d\d(.\d\d\d)?)?/g, "");
}

// 忽略小数
function ignoreDecimal(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', replaceDecimal(lText));
	$("#mergely").mergely('rhs', replaceDecimal(rText));
};

function replaceDecimal(source){
    if (!source) {
        return "";
    }
    return source.replace(/(\d{1,16})\.\d{1,16}/g, "$1");
}

// 忽略整数
function ignoreNumber(){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', replaceNumber(lText));
	$("#mergely").mergely('rhs', replaceNumber(rText));
};

function replaceNumber(source){
    if (!source) {
        return "";
    }
    return source.replace(/\d{1,16}(\.\d{1,16}(E\d{1,3})?)?/g, "0");
}

function replaceData() {
    // 获取当前选中项的值
    var mode = document.getElementById("ignore_select").value;
    if (mode == "align") {
        align();
    } else if (mode == "time") {
        ignoreTime();
    } else if (mode == "dateTime") {
        ignoreDateTime();
    } else if (mode == "null") {
        ignoreNull();
    } else if (mode == "decimal") {
        ignoreDecimal();
    } else if (mode == "number") {
        ignoreNumber();
    }
}

// 对齐表头
function align(event){
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');

	// 根据首行数据判断分隔符, 优先级依次为 \t 逗号 空格
	var splitChar = "\t";
	var lines = lText.split("\n")
	var line1 = lines[0].trim();
	if (event.altKey) {
	    // 按下 alt 键时, 直接用空格做分隔符
	    splitChar = " ";
	} else if (line1.indexOf("\t") == -1 && line1.indexOf(",") > 0 && line1.trim().endsWith(",") === false) {
	    splitChar = ",";
	} else if (line1.indexOf("\t") == -1 && line1.indexOf(" ") > 0) {
	    splitChar = " ";
	}

	$("#mergely").mergely('lhs', alignLine(lText, splitChar));
	$("#mergely").mergely('rhs', alignLine(rText, splitChar));
};

function alignLine(source, splitChar){
    if (!source) {
        return "";
    }
    if (splitChar == " ") {
        // 空格做分隔符时, 先删除连续空格
        source = source.replace(/ +/g, " ");
    }
	var lines = source.split("\n")
	for(var i in lines){
		lines[i] = lines[i].trim();
	}
	// 先获取每一列最大宽度
	var columnMaxLength = [];
	for(var i in lines){
		var chars = lines[i].split(splitChar);
		for(var j in chars){
			var c = columnMaxLength[j] ? columnMaxLength[j] :0;
			var l = chars[j] ? gbLen(chars[j]) : 0 ;
			columnMaxLength[j] = Math.max(c, l);
		}
	}
	// 然后将每一个值扩充到最大宽度
	var res = [];
	for(var i in lines){
		var resLine = [];
		var chars = lines[i].split(splitChar);
		for(var j in chars){
		    if (j != chars.length - 1) {
			    resLine[j] = padGbLength(chars[j], columnMaxLength[j] + 1, " ");
			} else {
			    resLine[j] = chars[j];
			}
		}
		var line = resLine.join("");
		res.push(line)
	}
	return res.join("\n");
}

// 字符宽度中文算2
function gbLen(source) {
    var len = 0;
    for (var i=0; i<source.length; i++) {
        if (source.charCodeAt(i)>127 || source.charCodeAt(i)==94) {
             len += 2;
         } else {
             len ++;
         }
     }
    return len;
}

// 在结尾不全中文字符串长度
function padGbLength(source, fillNum, fillChar) {
	let len = gbLen('' + source);
	var res = source;
	if (fillNum > len) {
		res = source + Array(fillNum - len + 1 || 0).join(fillChar);
	}
	return res;
}

// 替换换行
function splitBreak(splits){
	if (!splits) {
		splits = $('#splitChars').val();
	}
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', breakLine(lText, splits));
	$("#mergely").mergely('rhs', breakLine(rText, splits));
};

function breakLine(source, splits){
	var res = source;
	if (splits) {
		for (var i=0; i<splits.length; i++) {
			var split = splits.charAt(i)
			if (split == ')' || split == '}' || split == '])') {
				res = res.replaceAll("\n" + split, split).replaceAll(split,  "\n" + split);
			} else {
				res = res.replaceAll(split + "\n", split).replaceAll(split, split + "\n");
			}
		}
	}
	return res;
}
function setModeChange() {
    // 获取当前选中项的值
    var mode = document.getElementById("mode_select").value;
    // 设置代码模式
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	var param = "l=" + encodeURIComponent(lText) + "&r=" + encodeURIComponent(rText);
	var pzip = zip(param);

    var ignorecaseStr = getQueryString('ignorecase');
    var ignorecaseVar = !ignorecaseStr || ignorecaseStr != "false";
	window.location.href= "?z=" + pzip + "&ignorecase=" + ignorecaseVar + "&mode=" + mode;
}
function replaceAction() {
    // 获取当前选中项的值
    var v1 = document.getElementById("replace_1_input").value;
    var v2 = document.getElementById("replace_2_input").value;
    if (v1 != '') {
        var lText = $("#mergely").mergely('get', 'lhs');
        var rText = $("#mergely").mergely('get', 'rhs');
        $("#mergely").mergely('lhs', lText.replace(new RegExp(v1,'ig'), v2));
        $("#mergely").mergely('rhs', rText.replace(new RegExp(v1,'ig'), v2));
	}
}


// 删除列
function removeColumn(){
    var removeColumnName = document.getElementById("removeColumnName").value;
	var lText = $("#mergely").mergely('get', 'lhs');
	var rText = $("#mergely").mergely('get', 'rhs');
	$("#mergely").mergely('lhs', removeColumnBySplit(lText, removeColumnName));
	$("#mergely").mergely('rhs', removeColumnBySplit(rText, removeColumnName));
};
function removeColumnBySplit(source, removeColumnName){
	 if (!source) {
        return "";
    }
	var lines = source.split("\n")
	var splitChar = "\t";
	// 先获取每一列最大宽度
	var columnMaxLength = [];
	for(var i in lines){
		var chars = lines[i].split(splitChar);
		for(var j in chars){
			var c = columnMaxLength[j] ? columnMaxLength[j] :0;
			var l = chars[j] ? gbLen(chars[j]) : 0 ;
			columnMaxLength[j] = Math.max(c, l);
		}
	}
	if(columnMaxLength.length == 1) {
	    // 没有 \t 则用逗号
	    splitChar = ",";
	    columnMaxLength = [];
        for(var i in lines){
            var chars = lines[i].split(splitChar);
            for(var j in chars){
                var c = columnMaxLength[j] ? columnMaxLength[j] :0;
                var l = chars[j] ? gbLen(chars[j]) : 0 ;
                columnMaxLength[j] = Math.max(c, l);
            }
        }
	}
	var removeColumnIdx = -1;
	var columnNames = lines[0].split(splitChar);
     for(var i in columnNames){
        if (columnNames[i] == removeColumnName) {
            removeColumnIdx = i;
        }
    }
    if (removeColumnIdx == -1) {
        return source;
    }

	// 输出其他列
	var res = [];
	for(var i in lines){
		var resLine = [];
		var chars = lines[i].split(splitChar);
		chars.splice(removeColumnIdx, 1);
		var line = chars.join(splitChar);
		res.push(line)
	}
	return res.join("\n");
}

    </script>
</head>
<body>
<div class="mergely-full-screen-0">
    <div>
        <button onclick="newWindow()">新窗口打开</button>
        |
        <span>配色:</span>
        <select id="mode_select" onchange="setModeChange()">
            <option value="">none</option>
<!--            <option value="text/html">html</option>-->
            <option value="text/css">css</option>
<!--            <option value="text/javascript">javascript</option>-->
            <option value="text/sysql">sysql</option>
            <option value="text/x-sql">sql</option>
            <option value="text/x-mysql">mysql</option>
            <option value="text/x-pgsql">pgsql</option>
        </select>
        <button onclick="$('.sortLine').toggle();sortLine(true)" class="sortLine">升序</button>
        <button onclick="$('.sortLine').toggle();sortLine(false)" class="sortLine hidden">降序</button>
        <button onclick="$('.strUpperCase').toggle();strUpperCase(true)" class="strUpperCase">大写</button>
        <button onclick="$('.strUpperCase').toggle();strUpperCase(false)" class="strUpperCase hidden">小写</button>
        <button onclick="align(event)" title="从首行依次查找\t逗号空格作为分隔符,按下alt点击本按钮强制用空格做分隔符">对齐表头</button>
        <button onclick="ignorecaseAction()">区分大小写</button>
        <button onclick="wrapLinesAction()">自动换行</button>
        |
        <label>
            <span>替换:</span>
            <select id="ignore_select" onchange="replaceData()">
                <option value="time">时分秒</option>
                <option value="dateTime">年月日时分秒</option>
                <option value="null">null</option>
                <option value="decimal">小数</option>
                <option value="number">数字</option>
            </select>
        </label>
        |
        <label>
            <span>替换换行:</span>
            <input id="splitChars" name="splitChars" type="text" value="{()};" style="width:5em;"/>
            <button onclick="splitBreak()">换行</button>
        </label>
        |
        <label>
            <input id="replace_1_input" name="replace_1" style="width:8em;"/>=>
            <input id="replace_2_input" name="replace_2" style="width:8em;"/>
            <button onclick="replaceAction()">替换</button>
        </label>
        |
        <label>
            <span>删除列:</span>
            <input id="removeColumnName" name="removeColumnName" type="text" value="" style="width:5em;"/>
            <button onclick="removeColumn()">删除</button>
        </label>
    </div>
    <div class="mergely-resizer">
        <div id="mergely">
        </div>
    </div>
</div>
</body>
</html>
